<!DOCTYPE html>
<html lang="en">
<head>
    
    <meta charset="utf-8">
    <title>my-particle/src/Particle.vue - Documentation</title>
    
    
    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <link type="text/css" rel="stylesheet" href="styles/prettify.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
    <script src="scripts/nav.js" defer></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav >
    
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Outline.html">Outline</a></li><li><a href="Tag.html">Tag</a></li><li><a href="TagCanvas.html">TagCanvas</a></li></ul><h3>Modules</h3><ul><li><a href="module-$ui_components_my-affix.html">$ui/components/my-affix</a></li><li><a href="module-$ui_components_my-anchor.html">$ui/components/my-anchor</a></li><li><a href="module-$ui_components_my-at-input.html">$ui/components/my-at-input</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-at-input.html#~getData">getData</a></li><li data-type='method'><a href="module-$ui_components_my-at-input.html#~setData">setData</a></li><li data-type='method'><a href="module-$ui_components_my-at-input.html#~tagInsert">tagInsert</a></li><li data-type='method'><a href="module-$ui_components_my-at-input.html#~togglePopover">togglePopover</a></li></ul></li><li><a href="module-$ui_components_my-autocomplete.html">$ui/components/my-autocomplete</a></li><li><a href="module-$ui_components_my-avatar.html">$ui/components/my-avatar</a></li><li><a href="module-$ui_components_my-avatars.html">$ui/components/my-avatars</a></li><li><a href="module-$ui_components_my-back-top.html">$ui/components/my-back-top</a></li><li><a href="module-$ui_components_my-breadcrumb.html">$ui/components/my-breadcrumb</a></li><li><a href="module-$ui_components_my-capture.html">$ui/components/my-capture</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-capture.html#~_renderImg">_renderImg</a></li></ul></li><li><a href="module-$ui_components_my-card-list.html">$ui/components/my-card-list</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-card-list.html#~refresh">refresh</a></li></ul></li><li><a href="module-$ui_components_my-cascader.html">$ui/components/my-cascader</a></li><li><a href="module-$ui_components_my-checkbox.html">$ui/components/my-checkbox</a></li><li><a href="module-$ui_components_my-clipboard.html">$ui/components/my-clipboard</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-clipboard.html#~copy">copy</a></li></ul></li><li><a href="module-$ui_components_my-color-picker.html">$ui/components/my-color-picker</a></li><li><a href="module-$ui_components_my-contextmenu.html">$ui/components/my-contextmenu</a></li><li><a href="module-$ui_components_my-corner-mark.html">$ui/components/my-corner-mark</a></li><li><a href="module-$ui_components_my-crud.html">$ui/components/my-crud</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-crud.html#~openAddDialog">openAddDialog</a></li><li data-type='method'><a href="module-$ui_components_my-crud.html#~refresh">refresh</a></li><li data-type='method'><a href="module-$ui_components_my-crud.html#~reload">reload</a></li></ul></li><li><a href="module-$ui_components_my-date.html">$ui/components/my-date</a></li><li><a href="module-$ui_components_my-date-picker.html">$ui/components/my-date-picker</a></li><li><a href="module-$ui_components_my-description.html">$ui/components/my-description</a></li><li><a href="module-$ui_components_my-detail.html">$ui/components/my-detail</a></li><li><a href="module-$ui_components_my-detail-item.html">$ui/components/my-detail-item</a></li><li><a href="module-$ui_components_my-dialog.html">$ui/components/my-dialog</a></li><li><a href="module-$ui_components_my-drag.html">$ui/components/my-drag</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-drag.html#~getRelativeEl">getRelativeEl</a></li></ul></li><li><a href="module-$ui_components_my-drop.html">$ui/components/my-drop</a></li><li><a href="module-$ui_components_my-edit-tags.html">$ui/components/my-edit-tags</a></li><li><a href="module-$ui_components_my-editor.html">$ui/components/my-editor</a></li><li><a href="module-$ui_components_my-empty.html">$ui/components/my-empty</a></li><li><a href="module-$ui_components_my-filter.html">$ui/components/my-filter</a></li><li><a href="module-$ui_components_my-fixed.html">$ui/components/my-fixed</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-fixed.html#~resize">resize</a></li></ul></li><li><a href="module-$ui_components_my-flex.html">$ui/components/my-flex</a></li><li><a href="module-$ui_components_my-flex-item.html">$ui/components/my-flex-item</a></li><li><a href="module-$ui_components_my-flip.html">$ui/components/my-flip</a></li><li><a href="module-$ui_components_my-float.html">$ui/components/my-float</a></li><li><a href="module-$ui_components_my-float-item.html">$ui/components/my-float-item</a></li><li><a href="module-$ui_components_my-form.html">$ui/components/my-form</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-form.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-form.html#~submit">submit</a></li></ul></li><li><a href="module-$ui_components_my-form_src_Base.html">$ui/components/my-form/src/Base</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html">$ui/components/my-form/src/common/TagInput</a></li><li><a href="module-$ui_components_my-form_src_common_TagSelect.html">$ui/components/my-form/src/common/TagSelect</a></li><li><a href="module-$ui_components_my-form_src_common_TreeSelect.html">$ui/components/my-form/src/common/TreeSelect</a></li><li><a href="module-$ui_components_my-header.html">$ui/components/my-header</a></li><li><a href="module-$ui_components_my-highlight.html">$ui/components/my-highlight</a></li><li><a href="module-$ui_components_my-icon.html">$ui/components/my-icon</a></li><li><a href="module-$ui_components_my-im-wall.html">$ui/components/my-im-wall</a></li><li><a href="module-$ui_components_my-input.html">$ui/components/my-input</a></li><li><a href="module-$ui_components_my-input-number.html">$ui/components/my-input-number</a></li><li><a href="module-$ui_components_my-layout.html">$ui/components/my-layout</a></li><li><a href="module-$ui_components_my-lazy.html">$ui/components/my-lazy</a></li><li><a href="module-$ui_components_my-list.html">$ui/components/my-list</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-list.html#~load">load</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~refresh">refresh</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-list.html#~scrollTop">scrollTop</a></li></ul></li><li><a href="module-$ui_components_my-location-picker.html">$ui/components/my-location-picker</a></li><li><a href="module-$ui_components_my-login.html">$ui/components/my-login</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-login.html#~submit">submit</a></li></ul></li><li><a href="module-$ui_components_my-marquee.html">$ui/components/my-marquee</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-marquee.html#~pause">pause</a></li><li data-type='method'><a href="module-$ui_components_my-marquee.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-marquee.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-master-app.html">$ui/components/my-master-app</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-master-app.html#~initState">initState</a></li><li data-type='method'><a href="module-$ui_components_my-master-app.html#~onStateChange">onStateChange</a></li><li data-type='method'><a href="module-$ui_components_my-master-app.html#~onStateChange">onStateChange</a></li><li data-type='method'><a href="module-$ui_components_my-master-app.html#~setState">setState</a></li></ul></li><li><a href="module-$ui_components_my-menu.html">$ui/components/my-menu</a></li><li><a href="module-$ui_components_my-micro-app.html">$ui/components/my-micro-app</a></li><li><a href="module-$ui_components_my-navbar.html">$ui/components/my-navbar</a></li><li><a href="module-$ui_components_my-navbar-FullScreenAction.html">$ui/components/my-navbar-FullScreenAction</a></li><li><a href="module-$ui_components_my-navbar-IconAction.html">$ui/components/my-navbar-IconAction</a></li><li><a href="module-$ui_components_my-navbar-UserAction.html">$ui/components/my-navbar-UserAction</a></li><li><a href="module-$ui_components_my-number.html">$ui/components/my-number</a></li><li><a href="module-$ui_components_my-panel.html">$ui/components/my-panel</a></li><li><a href="module-$ui_components_my-paragraph.html">$ui/components/my-paragraph</a></li><li><a href="module-$ui_components_my-particle.html">$ui/components/my-particle</a></li><li><a href="module-$ui_components_my-pro.html">$ui/components/my-pro</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-pro.html#~addTab">addTab</a></li><li data-type='method'><a href="module-$ui_components_my-pro.html#~closeTabs">closeTabs</a></li><li data-type='method'><a href="module-$ui_components_my-pro.html#~setTab">setTab</a></li></ul></li><li><a href="module-$ui_components_my-promise.html">$ui/components/my-promise</a></li><li><a href="module-$ui_components_my-radial-menu.html">$ui/components/my-radial-menu</a></li><li><a href="module-$ui_components_my-radio.html">$ui/components/my-radio</a></li><li><a href="module-$ui_components_my-range.html">$ui/components/my-range</a></li><li><a href="module-$ui_components_my-rate.html">$ui/components/my-rate</a></li><li><a href="module-$ui_components_my-resize.html">$ui/components/my-resize</a></li><li><a href="module-$ui_components_my-result.html">$ui/components/my-result</a></li><li><a href="module-$ui_components_my-revolve.html">$ui/components/my-revolve</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-revolve.html#~next">next</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~prev">prev</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-revolve.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-search-box.html">$ui/components/my-search-box</a></li><li><a href="module-$ui_components_my-select.html">$ui/components/my-select</a></li><li><a href="module-$ui_components_my-sidebar.html">$ui/components/my-sidebar</a></li><li><a href="module-$ui_components_my-skeleton.html">$ui/components/my-skeleton</a></li><li><a href="module-$ui_components_my-slide-layout.html">$ui/components/my-slide-layout</a></li><li><a href="module-$ui_components_my-slider.html">$ui/components/my-slider</a></li><li><a href="module-$ui_components_my-sortable.html">$ui/components/my-sortable</a></li><li><a href="module-$ui_components_my-spin.html">$ui/components/my-spin</a></li><li><a href="module-$ui_components_my-stat-card.html">$ui/components/my-stat-card</a></li><li><a href="module-$ui_components_my-switch.html">$ui/components/my-switch</a></li><li><a href="module-$ui_components_my-table.html">$ui/components/my-table</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-table.html#~refresh">refresh</a></li></ul></li><li><a href="module-$ui_components_my-tabs.html">$ui/components/my-tabs</a></li><li><a href="module-$ui_components_my-tag-canvas.html">$ui/components/my-tag-canvas</a></li><li><a href="module-$ui_components_my-tag-input.html">$ui/components/my-tag-input</a></li><li><a href="module-$ui_components_my-tag-select.html">$ui/components/my-tag-select</a></li><li><a href="module-$ui_components_my-text.html">$ui/components/my-text</a></li><li><a href="module-$ui_components_my-three-menu.html">$ui/components/my-three-menu</a></li><li><a href="module-$ui_components_my-timer.html">$ui/components/my-timer</a><ul class='methods'><li data-type='method'><a href="module-$ui_components_my-timer.html#~reset">reset</a></li><li data-type='method'><a href="module-$ui_components_my-timer.html#~start">start</a></li><li data-type='method'><a href="module-$ui_components_my-timer.html#~stop">stop</a></li></ul></li><li><a href="module-$ui_components_my-title.html">$ui/components/my-title</a></li><li><a href="module-$ui_components_my-tree-select.html">$ui/components/my-tree-select</a></li><li><a href="module-$ui_components_my-typography.html">$ui/components/my-typography</a></li><li><a href="module-$ui_components_my-water-fall.html">$ui/components/my-water-fall</a></li><li><a href="module-$ui_components_my-watermark.html">$ui/components/my-watermark</a></li><li><a href="module-$ui_components_my-wave.html">$ui/components/my-wave</a></li><li><a href="module-$ui_components_my-wrapper.html">$ui/components/my-wrapper</a></li><li><a href="module-widgets_my-print.html">widgets/my-print</a></li></ul><h3>Events</h3><ul><li><a href="module-$ui_components_my-stat-card.html#~event:action">action</a></li><li></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:add">add</a></li><li><a href="module-$ui_components_my-wrapper.html#~event:back">back</a></li><li><a href="module-$ui_components_my-dialog.html#~event:cancel">cancel</a></li><li><a href="module-$ui_components_my-typography.html#~event:change">change</a></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-tag-canvas.html#~event:click">click</a></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-avatars.html#~event:click-add">click-add</a></li><li><a href="module-$ui_components_my-avatars.html#~event:click-item">click-item</a></li><li><a href="module-$ui_components_my-avatars.html#~event:click-more">click-more</a></li><li><a href="module-$ui_components_my-radial-menu.html#~event:close">close</a></li><li></li><li><a href="module-$ui_components_my-pro.html#~event:collapse">collapse</a></li><li><a href="module-$ui_components_my-form_src_common_TagSelect.html#~event:collapsed">collapsed</a></li><li><a href="module-$ui_components_my-table.html#~event:column-change">column-change</a></li><li><a href="module-$ui_components_my-navbar-UserAction.html#~event:command">command</a></li><li></li><li></li><li><a href="global.html#event:complete">complete</a></li><li></li><li><a href="module-$ui_components_my-typography.html#event:copy">copy</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-drag.html#~event:drag">drag</a></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:drag-start">drag-start</a></li><li><a href="module-$ui_components_my-dialog.html#~event:drag-stop">drag-stop</a></li><li><a href="module-$ui_components_my-drop.html#~event:drop">drop</a></li><li><a href="module-$ui_components_my-typography.html#event:edited">edited</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-typography.html#event:editing">editing</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-drop.html#~event:enter">enter</a></li><li><a href="module-$ui_components_my-table.html#~event:error">error</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-typography.html#event:expand">expand</a></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:finish">finish</a></li><li><a href="module-$ui_components_my-dialog.html#~event:hide">hide</a></li><li><a href="module-$ui_components_my-lazy.html#~event:init">init</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:input-change">input-change</a></li><li><a href="module-$ui_components_my-drop.html#~event:leave">leave</a></li><li><a href="module-$ui_components_my-wrapper.html#~event:link-click">link-click</a></li><li><a href="module-$ui_components_my-dialog.html#~event:load">load</a></li><li><a href="module-$ui_components_my-revolve.html#~event:loaded">loaded</a></li><li><a href="module-$ui_components_my-dialog.html#~event:maximize">maximize</a></li><li><a href="module-$ui_components_my-im-wall.html#~event:on-added">on-added</a></li><li><a href="module-$ui_components_my-capture.html#~event:on-capture">on-capture</a></li><li><a href="global.html#event:on-change">on-change</a></li><li><a href="module-$ui_components_my-capture.html#~event:on-output">on-output</a></li><li><a href="module-$ui_components_my-at-input.html#~event:on-popToggle">on-popToggle</a></li><li></li><li><a href="module-$ui_components_my-slide-layout.html#~event:on-ready">on-ready</a></li><li><a href="module-$ui_components_my-slide-layout.html#~event:on-resize">on-resize</a></li><li><a href="module-$ui_components_my-at-input.html#~event:on-tagEdit">on-tagEdit</a></li><li><a href="module-$ui_components_my-radial-menu.html#~event:open">open</a></li><li></li><li><a href="module-$ui_components_my-drop.html#~event:over">over</a></li><li><a href="global.html#~event:page-change">page-change</a></li><li></li><li></li><li><a href="module-$ui_components_my-login.html#~event:pki">pki</a></li><li><a href="module-$ui_components_my-revolve.html#~event:progress">progress</a></li><li><a href="module-$ui_components_my-form_src_common_TagInput.html#~event:remove">remove</a></li><li><a href="module-$ui_components_my-timer.html#~event:reset">reset</a></li><li></li><li><a href="module-$ui_components_my-resize.html#~event:resize">resize</a></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:resize-start">resize-start</a></li><li><a href="module-$ui_components_my-dialog.html#~event:resize-stop">resize-stop</a></li><li><a href="module-$ui_components_my-search-box.html#~event:search">search</a></li><li><a href="module-$ui_components_my-sidebar.html#~event:select">select</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-dialog.html#~event:show">show</a></li><li><a href="global.html#~event:size-change">size-change</a></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:start">start</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-timer.html#~event:stop">stop</a></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-login.html#~event:submit">submit</a></li><li></li><li></li><li><a href="module-$ui_components_my-table.html#~event:success">success</a></li><li></li><li></li><li></li><li></li><li></li><li><a href="module-$ui_components_my-panel.html#~event:tab-change">tab-change</a></li><li><a href="module-$ui_components_my-pro.html#~event:tab-remove">tab-remove</a></li><li><a href="module-$ui_components_my-pro.html#~event:tab-select">tab-select</a></li><li><a href="module-$ui_components_my-timer.html#~event:tick">tick</a></li><li><a href="module-$ui_components_my-form.html#~event:validate">validate</a></li><li><a href="module-$ui_components_my-form.html#~event:validate-fail">validate-fail</a></li><li><a href="module-$ui_components_my-form.html#~event:validate-success">validate-success</a></li><li><a href="module-widgets_my-back-top.html#event:click">click</a></li></ul><h3>Global</h3><ul><li><a href="global.html#AddShadowToImage">AddShadowToImage</a></li><li><a href="global.html#appendChildNode">appendChildNode</a></li><li><a href="global.html#createEllipsisContainer">createEllipsisContainer</a></li><li><a href="global.html#createEllipsisContentHolder">createEllipsisContentHolder</a></li><li><a href="global.html#destroyVue">destroyVue</a></li><li><a href="global.html#getData">getData</a></li><li><a href="global.html#inRange">inRange</a></li><li><a href="global.html#instanceVue">instanceVue</a></li><li><a href="global.html#props">props</a></li><li><a href="global.html#pxToNumber">pxToNumber</a></li><li><a href="global.html#removeEllipsisContainer">removeEllipsisContainer</a></li><li><a href="global.html#RoundImage">RoundImage</a></li><li><a href="global.html#scrollTop">scrollTop</a></li><li><a href="global.html#setData">setData</a></li><li><a href="global.html#styleToString">styleToString</a></li><li><a href="global.html#wrapperDecorations">wrapperDecorations</a></li></ul>
</nav>

<div id="main">
    
    <h1 class="page-title">my-particle/src/Particle.vue</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>&lt;template>
    &lt;div class="my-particle"  :style="styles">
      &lt;slot>&lt;/slot>
    &lt;/div>
&lt;/template>
&lt;script>
  /**
   * 粒子特效
   * @author 李国师 chester
   * @module $ui/components/my-particle
   */
    import {addResizeListener, removeResizeListener} from 'element-ui/lib/utils/resize-event'
  const defaultOptions = {
    maxNum: 200, // 粒子数量
    initSpeed: 50, // 每秒新增的粒子数
    radius: 1.5, // 粒子半径区间, 数字或数组
    speed: 0.5, // 运动速度最大值
    scaleSpeed: 0.01, // expand 或 shrink时有用，粒子放大速度
    direction: '', // 运动指向方向
    rebound: false, // 是否反弹
    hole: 50, // 黑洞半径
      // 字符串或数组, 数组时可在不同颜色循环变化 
        /*
         颜色变换数组
           [
              {
                  color: 'rgba(255,0,0,1)',
                  transitionTime: 1000, // 变换时长
                  duration: 5000   // 持续时间
              },
              {
                  color: 'rgba(0,255,0,1)',
                  transitionTime: 1000,
                  duration: 5000 
              }
          ]
        */
    color: 'rgba(0,188,212,0.9)'
  }
    /**
   * 插槽
   * @member slots
   * @property {string} default 默认插槽，定义其它内容
   */
    export default {
      name: 'MyParticle',
      /**
     * 属性参数
     * @member props
     * @property {object} [options] 粒子配置
     * @property {object} [options.maxNum] 粒子数量
     * @property {object} [options.initSpeed] 每秒新增的粒子数
     * @property {object} [options.radius] 粒子半径区间, 数字或数组
     * @property {object} [options.speed] 运动速度最大值
     * @property {object} [options.direction] 运动指向方向
     * @property {object} [options.rebound] 是否反弹
     * @property {object} [options.scaleSpeed] direction为expand 或 shrink时有用，粒子放大速度
     * @property {object} [options.hole] direction为expand 或 shrink时有用，黑洞半径
     * @property {string} [width] 画布宽
     * @property {string} [height] 画布高
     * @property {function} [handleParticle] 粒子属性处理方法
     * @property {function} [handleDraw] 粒子形状处理方法
     * @property {function} [initParticle] 粒子初始化方法
     * @property {string|Array} [color] 粒子颜色
     * @property {string} [color[].color] 粒子颜色
     * @property {number} [color[].duration] 颜色持续时间
     * @property {number} [color[].transitionTime] 颜色变换时间
     **/
      props: {
        options: {
          type: Object,
          default() {
            return {
            }
          }
        },
        width: {
          type: String,
          default: '100%'
        },
        height: {
          type: String,
          default: '400px'
        },
        handleParticle: {
          type: [Function]
        },
        handleDraw: {
          type: [Function]
        },
        initParticle: {
          type: [Function]
        }
      },
      watch: {
        options: {
          deep: true,
          handler() {
            this.reset()
          }
          }
      },
      computed: {
        styles() {
          return {
            width: this.width,
            height: this.height
          }
        }
      },
        data() {
            return {
                canvas: null,
                setArr: [],
                transColor: [],
                animateStop: false,
                drawOption: {},
                resetTimeout: null
            }
        },
        methods: {
            initOption() {
                let x, y, theta
                if(['shrink'].includes(this.drawOption.direction)) {
                    const offsetX = this.canvas.width * 0.5
                    const offsetY = this.canvas.height * 0.5
                    const ra = Math.max(offsetX, offsetY) - 100 + Math.random() * 100
                    theta = Math.random() * Math.PI * 2
                    x = offsetX + ra * Math.sin(theta)
                    y = offsetY + ra * Math.cos(theta)
                } else if(['expand'].includes(this.drawOption.direction)) { 
                    const ra = this.drawOption.hole + Math.random() * (this.drawOption.hole + 20)
                    theta = Math.random() * Math.PI * 2
                    x = this.canvas.width / 2 + ra * Math.cos(theta)
                    y = this.canvas.height / 2 + ra * Math.sin(theta)
                } else {
                    x = Math.ceil(Math.random() * this.canvas.width)
                    y = Math.ceil(Math.random() * this.canvas.height)
                }
                const speed = this.drawOption.speed
                let vX = 0, vY = 0
                    vX = (-speed + Math.random() * speed * 2) * 0.25
                    vY = -speed + Math.random() * speed * 2  
                if(this.drawOption.direction === 'bottom') {
                     vX = (-speed + Math.random() * speed * 2) * 0.25
                      vY = Math.random() * speed 
                } else if(this.drawOption.direction === 'top') {
                    vX = (-speed + Math.random() * speed * 2) * 0.25
                      vY = -Math.random() * speed   
                }else if(this.drawOption.direction === 'left') {
                      vX = -Math.random() * speed 
                      vY = (-speed + Math.random() * speed * 2) * 0.25  
                } else if(this.drawOption.direction === 'right') {
                      vX = Math.random() * speed   
                      vY = (-speed + Math.random() * speed * 2) * 0.25  
                } else if(this.drawOption.direction === 'shrink') {
                    const vR = Math.random() * speed
                     vY = -vR * Math.cos(theta)
                     vX = -vR * Math.sin(theta)
                } else if(this.drawOption.direction === 'expand') {
                     const vR = Math.random() * speed
                     vX = vR * Math.cos(theta)
                     vY = vR * Math.sin(theta)
                }
                let radius = 3
                if(this.drawOption.radius instanceof Array) {
                    radius = (this.drawOption.radius[0] || 0.5) + Math.ceil(Math.random() * ((this.drawOption.radius[1] || 2) - (this.drawOption.radius[0] || 0.5)))
                } else {
                    radius = 0.2 + Math.ceil(Math.random() * this.drawOption.radius)
                }
                let customObj = {}
                if(typeof this.initParticle === 'function') {
                  customObj = this.initParticle(this)
                }
                const obj = {
                    x,
                    y,
                    vX,
                    vY,
                    radius: radius,
                    color: '',
                    colorArr: [],
                    colorDelay: Math.floor(Math.random() * 1000),
                    ...customObj
                };
                return obj
            },
            setCanvas() {
                this.drawOption = Object.assign({}, defaultOptions, this.options)
                const canvas = document.createElement('canvas')
                this.canvas = canvas
                this.$el.appendChild(canvas)
                this.cxt = canvas.getContext('2d')
                 addResizeListener(this.$el, this.setScreenSize)
                 this.setScreenSize()
                this.reset()
            },
            setScreenSize() {
               const rect = this.$el.getBoundingClientRect()
                 this.canvas.width = rect.width
                this.canvas.height = rect.height
            },
            reset() {
              if(this.resetTimeout) {
                clearTimeout(this.resetTimeout)
              }
              this.resetTimeout = setTimeout(() => {
                this.animateStop = true
                  this.drawOption = Object.assign({}, defaultOptions, this.options)
                this.setArr = []
                if(this.drawOption.color instanceof Array) {
                      this.transColor = this.drawOption.color.map(r => {
                          const reg = /rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?((\d)|(\d(?:\.\d{1,5}?)))\))?/
                          const cMatch = r.color.match(reg)
                          const cArr = cMatch ? [parseFloat(cMatch[1]), parseFloat(cMatch[2]), parseFloat(cMatch[3]), parseFloat(typeof cMatch[4] === 'undefined' ? 1 : cMatch[4])] : ''
                          return {
                            ...r,
                            color: cArr 
                          }
                      })
                  }
                this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height)
                this.ballSet()
                this.animateStop = false
                this.ballDraw(this.cxt)
              }, 400)
            },
            ballSet () {
                const timer1 = setInterval(() => {
                    // 控制小球总数
                    if (this.setArr.length >= this.drawOption.maxNum) {
                        clearInterval(timer1);
                    }
                    const obj = this.initOption()
                    if (Math.abs(obj.vX) > 0.005 || Math.abs(obj.vY) > 0.005) { // 防止速度为0 ，不要静止的小球
                        this.setArr.push(obj);
                    }
                }, 1000 / this.drawOption.initSpeed); 
            },
            ballDraw (time) {
              if(this.animateStop) {
                return
              }
                // 绘制前要清空前一帧的画布
                this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height)
                
                this.setArr.forEach(item => {
                    // 遇到边界是否反弹
                    this.getPosition(item, time)
                    this.getColor(item, time)
                    if(typeof this.handleDraw !== 'function') {
                      this.drawParticle(this.cxt, item, time)
                    } else {
                      this.handleDraw(this.cxt, item, time)
                    }
                })
                  requestAnimationFrame(this.ballDraw)
            },
            drawParticle(cxt, item, time) {
                cxt.beginPath();
                cxt.fillStyle = item.color;
                cxt.arc(item.x, item.y, item.radius, 0, 2 * Math.PI);
                cxt.fill();
            },
            getColor(item, time) {
                if(typeof this.drawOption.color === 'string') {
                    item.color = this.drawOption.color
                } else {
                    if(typeof item.status === 'undefined' || item.colorDelay) {
                        item.colorDelay--
                        item.colorTime = time
                        item.status = 0
                        item.colorArr = this.transColor[item.status].color
                        item.color = `rgba(${item.colorArr[0]},${item.colorArr[1]},${item.colorArr[2]},${item.colorArr[3]})`
                    } else {
                        if(time - item.colorTime > this.transColor[item.status].duration) {
                            item.status++
                            item.status = item.status % this.transColor.length
                            item.colorTime = time
                        } else if((this.transColor[item.status].duration - (time - item.colorTime)) &lt; this.transColor[item.status].transitionTime) {
                            const nextStatus = (item.status + 1) % this.transColor.length
                            const nextColorArr = this.transColor[nextStatus].color
                            this.approtchColor(item, nextColorArr, time)
                        } else {
                            item.colorArr = this.transColor[item.status].color
                            item.color = `rgba(${item.colorArr[0]},${item.colorArr[1]},${item.colorArr[2]},${item.colorArr[3]})`
                        }
                    }
                }
            },
            approtchColor(item, nextColorArr, time) {
                const ratio = ((time - item.colorTime) - (this.transColor[item.status].duration - this.transColor[item.status].transitionTime)) / this.transColor[item.status].transitionTime
                const r = item.colorArr[0] + (nextColorArr[0] - item.colorArr[0]) * ratio
                const g = item.colorArr[1] + (nextColorArr[1] - item.colorArr[1]) * ratio
                const b = item.colorArr[2] + (nextColorArr[2] - item.colorArr[2]) * ratio
                const a = item.colorArr[3] + (nextColorArr[3] - item.colorArr[3]) * ratio
                item.color = `rgba(${r}, ${g}, ${b}, ${a})`
            },
            getPosition(item, time) {
                if(this.handleParticle &amp;&amp; typeof this.handleParticle === 'function') {
                    this.handleParticle(item, this.canvas, time)
                } else {
                  const speed = this.drawOption.speed
                    if(['shrink'].includes(this.drawOption.direction)) {
                        const dx = item.x - this.canvas.width / 2
                        const dy = item.y - this.canvas.height / 2
                        if(Math.sqrt(dx * dx + dy * dy) &lt; this.drawOption.hole) {
                            if(this.drawOption.radius instanceof Array) {
                                item.radius = (this.drawOption.radius[0] || 0.5) + Math.ceil(Math.random() * ((this.drawOption.radius[1] || 2) - (this.drawOption.radius[0] || 0.5)))
                            } else {
                                item.radius = 0.3 + Math.ceil(Math.random() * this.drawOption.radius)
                            }
                            const offsetX = this.canvas.width * 0.5
                            const offsetY = this.canvas.height * 0.5
                            const ra = Math.max(offsetX, offsetY) - 100 + Math.random() * 100
                            const theta = Math.random() * Math.PI * 2
                            item.x = offsetX + ra * Math.sin(theta)
                            item.y = offsetY + ra * Math.cos(theta)
                            const vR = Math.random() * speed
                            item.vY = -vR * Math.cos(theta)
                            item.vX = -vR * Math.sin(theta)
                        }
                        item.radius -= Math.max(Math.abs(item.vY), Math.abs(item.vX)) * this.drawOption.scaleSpeed
                        item.radius = item.radius &lt;= 0.1 ? 0.1 : item.radius
                    } else if(['expand'].includes(this.drawOption.direction)) {
                        if ((item.x + item.radius >= this.canvas.width) || (item.x - item.radius &lt;= 0) ||
                        (item.y + item.radius >= this.canvas.height) || (item.y - item.radius &lt;= 0)) {
                            if(this.drawOption.radius instanceof Array) {
                                item.radius = (this.drawOption.radius[0] || 0.5) + Math.ceil(Math.random() * ((this.drawOption.radius[1] || 2) - (this.drawOption.radius[0] || 0.5)))
                            } else {
                                item.radius = 0.3 + Math.ceil(Math.random() * this.drawOption.radius)
                            }
                            const ra = this.drawOption.hole + Math.random() * (this.drawOption.hole + 20)
                            const theta = Math.random() * Math.PI * 2
                            item.x = this.canvas.width / 2 + ra * Math.cos(theta)
                            item.y = this.canvas.height / 2 + ra * Math.sin(theta)
                            const vR = Math.random() * speed
                            item.vX = vR * Math.cos(theta)
                            item.vY = vR * Math.sin(theta)
                        }
                        item.radius += Math.max(Math.abs(item.vY), Math.abs(item.vX)) * this.drawOption.scaleSpeed
                    } else {
                        // 处理x坐标反弹
                        if ((item.x + item.radius >= this.canvas.width) || (item.x - item.radius &lt;= 0)) { 
                            if(this.drawOption.rebound) {
                                item.vX *= -1
                            } else {
                                item.x = item.vX &lt; 0 ? (this.canvas.width - item.radius) : item.radius
                            }
                        }
                        // 处理y坐标反弹
                        if ((item.y + item.radius >= this.canvas.height) || (item.y - item.radius &lt;= 0)) { 
                            if(this.drawOption.rebound) {
                                item.vY *= -1
                            } else {
                                item.y = item.vY &lt; 0 ? (this.canvas.height - item.radius) : item.radius
                            }
                        }
                    }
                    item.x += item.vX;
                    item.y += item.vY;
                }
                return item
            }
        },
        mounted() {
          this.animateStop = true
            this.setCanvas()
        },
         beforeDestroy() {
           this.animateStop = true
            removeResizeListener(this.$el, this.setScreenSize)
         }
    }
&lt;/script>
&lt;style type="text/scss" lang="scss" scoped>
&lt;/style>
</code></pre>
        </article>
    </section>





    
</div>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.6</a> on Sun May 30 2021 01:03:37 GMT+0800 (GMT+08:00) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>




<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?c4e5f73318b5cb0c389e3d9a05f831cc";
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();
</script>

</body>
</html>
